package com.rockwell.robot2015;

import java.util.ArrayList;

import net.wimpi.modbus.usbserial.SerialParameters;

import com.rockwell.robot2015.R;
import com.rockwell.robot2015.modbus.ModbusSerialClient;
import com.rockwell.robot2015.model.ColorBlobInfo;
import com.rockwell.robot2015.model.GameStage;
import com.rockwell.robot2015.model.IRobotLogger;
import com.rockwell.robot2015.model.MazePath;
import com.rockwell.robot2015.model.OnColorBlobDetectListener;
import com.rockwell.robot2015.model.OnOrientationChangeListener;
import com.rockwell.robot2015.model.Robot;
import com.rockwell.robot2015.model.RobotAction;
import com.rockwell.robot2015.model.RobotConfig;
import com.rockwell.robot2015.model.RobotLocation;
import com.rockwell.robot2015.model.command.RobotCommander;
import com.rockwell.robot2015.model.detectors.Maze1Detector;
import com.rockwell.robot2015.model.detectors.Maze2Detector;
import com.rockwell.robot2015.model.detectors.Maze3Detector;
import com.rockwell.robot2015.model.detectors.MazeEntranceGuideDetector;
import com.rockwell.robot2015.model.detectors.OuterWallDetector;
import com.rockwell.robot2015.model.detectors.DropAreaDetector;
//import com.rockwell.robot2015.model.detectors.ObstacleDetector;
import com.rockwell.robot2015.model.detectors.IDetector;
import com.rockwell.robot2015.model.detectors.TreasureDetector;
import com.rockwell.robot2015.model.sensors.RobotSensors;
import com.rockwell.robot2015.model.solvers.IMazeSolver;
import com.rockwell.robot2015.model.solvers.LoopMazeSolver;
import com.rockwell.robot2015.model.solvers.PredefinedMazeSolver;
import com.rockwell.robot2015.model.states.running.RobotRunningState;
import com.rockwell.robot2015.utils.Speaker;
import com.rockwell.robot2015.views.MazeCameraView;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.text.Editable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.UnderlineSpan;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class RobotActivity extends Activity {
	private GameStage m_gameStage;
	private Robot m_robot;
	private MazeCameraView m_mazeCameraView;
	private ModbusSerialClient m_modbusMaster;
	private Speaker m_speaker;
	private IDetector m_dropAreaDetector;
	private IDetector m_treasureDetector;
	private IDetector m_obstacleDetector;
	private IDetector m_maze1Detector;
	private IDetector m_maze2Detector;
	private IDetector m_maze3Detector;
	private IDetector m_mazeEntranceGuideDetector;
	private IDetector m_outerWallDetector;

	private RobotRunningState m_newState;
	
	private IRobotLogger m_logger = new IRobotLogger() {

		@Override
		public void log(final String msg) {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					TextView logDisplay = (TextView) findViewById(R.id.text_log);
					logDisplay.append(msg + "\n");

					// if (m_speaker != null)
					// m_speaker.speak(msg);
					// playSound(RobotActivity.this);
				}
			});
		}

		Exception m_lastException;
		
		@Override
		public void log(final Exception ex) {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					if (m_lastException == null) {
						m_lastException = ex;
						
						TextView logDisplay = (TextView) findViewById(R.id.text_log);
	
						if (ex.getMessage() != null) {
							logDisplay.append(ex.getMessage());
						}
	
						StackTraceElement[] trace = ex.getStackTrace();
						logDisplay.append(getTraceString(trace));
						logDisplay.append("\n");
					}
				}
			});
		}

		@Override
		public void setCurrentState(final String state) {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					TextView v = (TextView) findViewById(R.id.text_robot_status);
					v.setText(state);
				}
			});
		}
		
		public String getTraceString(StackTraceElement[] stackTraceElements) {
			if (stackTraceElements == null)
				return "";
			StringBuilder stringBuilder = new StringBuilder();
			for (StackTraceElement element : stackTraceElements)
				stringBuilder.append(element.toString()).append("\n");
			return stringBuilder.toString();
		}

		@Override
		public void onRobotPaused() {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					Button resume = (Button) findViewById(R.id.button_pause_resume);
					resume.setText("\tResume");
					// resume.setTextColor(0x0000ff);
					resume.setEnabled(true);

					TextView robotStatus = (TextView) findViewById(R.id.text_robot_status);

					String underLine = new String("Pause Mode");
					SpannableString content = new SpannableString(underLine);
					content.setSpan(new UnderlineSpan(), 0, underLine.length(),
							0);
					robotStatus.setText(underLine);

					if (m_speaker != null)
						m_speaker.speak("Please press start for me to run");
				}
			});
		}

		@Override
		public void onRobotResumed() {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					Button resume = (Button) findViewById(R.id.button_pause_resume);
					resume.setText("\tPause");
					// resume.setTextColor(0xff0000);
					resume.setEnabled(true);

					TextView robotStatus = (TextView) findViewById(R.id.text_robot_status);

					String underLine = new String("Run Mode");
					SpannableString content = new SpannableString(underLine);
					content.setSpan(new UnderlineSpan(), 0, underLine.length(),
							0);
					robotStatus.setText(underLine);

					if (m_speaker != null)
						m_speaker.speak("I'm Running");
				}
			});
		}

		@Override
		public void onRobotIdle() {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					Button resume = (Button) findViewById(R.id.button_pause_resume);
					resume.setText("");
					resume.setEnabled(false);

					TextView robotStatus = (TextView) findViewById(R.id.text_robot_status);

					String underLine = new String("Idle Mode");
					SpannableString content = new SpannableString(underLine);
					content.setSpan(new UnderlineSpan(), 0, underLine.length(),
							0);
					robotStatus.setText(underLine);

					if (m_speaker != null)
						m_speaker.speak("I'm restarting");
				}
			});
		}
	};

	private OnOrientationChangeListener m_orientationListener = new OnOrientationChangeListener() {
		public void onOrientationChanged(float[] orientation) {
			m_robot.setOrientation(orientation[0]);
		}
	};

	private OnColorBlobDetectListener m_treasureListener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {
			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_treasureDetector.onDetect(present, info,
							length, width);

					String msg;
					msg = String.format("T[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_treasureDetector.isPresent() ? "T" : "F");

					TextView treasurePosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_treasure_position);
					treasurePosition.setText(msg);

					/*
					TextView logDisplay = (TextView) findViewById(R.id.text_log);
					
					// added by daniel on Oct 15 to check if treasure is on the
					// left/right by how much, can use this for pid moving
					// straight
					if (m_treasureDetector.isPresent()) {
						if (center.y > (length / 2)) {
							//logDisplay.setText("Treasure is on the left "
							//		+ (center.y - length / 2) + "\n");
							m_logger.log("Treasure is on the left "
									+ (center.y - length / 2));
						} else {
							//logDisplay.setText("Treasure is on the right "
							//		+ (length / 2 - center.y) + "\n");
							m_logger.log("Treasure is on the right "
									+ (length / 2 - center.y));
						}
					} else {
						//logDisplay.setText("Treasure not found yet");
						m_logger.log("Treasure not found yet");
					}
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_obstacleListener = new OnColorBlobDetectListener() {
		boolean enabled = false;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_obstacleDetector.onDetect(present, info,
							length, width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_obstacleDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_mazeEntranceGuideListener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_mazeEntranceGuideDetector.onDetect(present, info, length, width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_obstacleDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_dropAreaListener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_dropAreaDetector.onDetect(present, info,
							length, width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_dropAreaDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_outerWallListener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_outerWallDetector.onDetect(present, info,
							length, width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_obstacleDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_maze1Listener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_maze1Detector.onDetect(present, info, length,
							width);

					/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_maze1Detector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_maze2Listener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_maze2Detector.onDetect(present, info, length,
							width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_obstacleDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);
					*/
				}
			});
		}
	};

	private OnColorBlobDetectListener m_maze3Listener = new OnColorBlobDetectListener() {
		boolean enabled = true;

		@Override
		public boolean isEnabled() {
			return enabled;
		}

		@Override
		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}
		
		public void onDetected(final boolean present, final ColorBlobInfo info, final int length, final int width) {

			RobotActivity.this.runOnUiThread(new Runnable() {
				public void run() {
					m_maze3Detector.onDetect(present, info, length,
							width);
/*
					String msg;
					msg = String.format("B[%d,%d,%d,%s]", (int) info.center.x,
							(int) info.center.y, (int) info.radius,
							m_obstacleDetector.isPresent() ? "T" : "F");

					TextView barrierPosition = (TextView) RobotActivity.this
							.findViewById(R.id.text_barrier_position);
					barrierPosition.setText(msg);*/
				}
			});
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_robot);

		Intent intent = getIntent();
		m_gameStage = GameStage.values()[intent.getIntExtra("stage",
				GameStage.Finals.ordinal())];

		m_mazeCameraView = (MazeCameraView) this
				.findViewById(R.id.maze_camera_view);
		m_mazeCameraView.setTeachMode(false);
		m_mazeCameraView.setOrientationChangeListener(m_orientationListener);

		m_mazeCameraView.setTreasureListener(m_treasureListener);
		//m_mazeCameraView.setObstacleListener(m_obstacleListener);
		m_mazeCameraView.setMaze1Listener(m_maze1Listener);
		m_mazeCameraView.setMaze2Listener(m_maze2Listener);
		m_mazeCameraView.setMaze3Listener(m_maze3Listener);
		m_mazeCameraView
				.setMazeEntranceGuideListener(m_mazeEntranceGuideListener);
		m_mazeCameraView.setOuterWallListener(m_outerWallListener);
		m_mazeCameraView.setDropAreaListener(m_dropAreaListener);

		SerialParameters params = new SerialParameters();
		params.setPortName("COM1");
		params.setBaudRate(19200);
		params.setDatabits(8);
		params.setParity("None");
		params.setStopbits(1);
		params.setEncoding("ascii");
		params.setEcho(false);

		UsbManager usb = (UsbManager) getSystemService(Context.USB_SERVICE);
		m_modbusMaster = new ModbusSerialClient(usb);

		final ScrollView sv = (ScrollView) findViewById(R.id.scrollview_log);
		TextView tv = (TextView) findViewById(R.id.text_log);
		tv.addTextChangedListener(new TextWatcher() {

			@Override
			public void afterTextChanged(Editable arg0) {
				sv.fullScroll(ScrollView.FOCUS_DOWN);
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// TODO Auto-generated method stub

			}

		});

		setupStateSpinner();
		setupSetStateButton();
		setupRestartButton();
		setupRobotPauseResumeButton();
		setupStopButton();
		setupClearLogButton();
		setupCopyLogButton();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.robot, menu);
		return true;
	}

	@Override
	public void onStart() {
		super.onStart();

		try {
			m_speaker = new Speaker(this);

			double width = SettingsActivity.getRobotWidth(this);
			double length = SettingsActivity.getRobotLength(this);

			RobotSensors sensors = new RobotSensors(m_modbusMaster);
			RobotCommander robotCommander = new RobotCommander(m_modbusMaster);
			m_treasureDetector = new TreasureDetector(m_treasureListener);
			//m_obstacleDetector = new ObstacleDetector(m_obstacleListener);
			m_maze1Detector = new Maze1Detector(m_maze1Listener);
			m_maze2Detector = new Maze2Detector(m_maze2Listener);
			m_maze3Detector = new Maze3Detector(m_maze3Listener);
			m_mazeEntranceGuideDetector = new MazeEntranceGuideDetector(m_mazeEntranceGuideListener);
			m_outerWallDetector = new OuterWallDetector(m_outerWallListener);
			m_dropAreaDetector = new DropAreaDetector(m_dropAreaListener);

			IMazeSolver predefineSolver = null;

			if (SettingsActivity.usePredefinedPath(this)
					&& SettingsActivity.hasPredefinedPath(this)) {
				ArrayList<Integer> distances = new ArrayList<Integer>();
				ArrayList<RobotLocation> junctions = new ArrayList<RobotLocation>();
				ArrayList<RobotAction> directions = new ArrayList<RobotAction>();

				if (MazePath.loadPredefinedPath(this, distances, junctions,
						directions)) {
					predefineSolver = new PredefinedMazeSolver(junctions, directions,
							new LoopMazeSolver(false), m_logger);
				}
			}

			RobotConfig config = new RobotConfig();
			config.width = width;
			config.length = length;
			config.sensors = sensors;
			config.commander = robotCommander;
			config.predefinedMazeSolver = predefineSolver;
			config.treasureDetector = m_treasureDetector;
			//config.obstacleDetector = m_obstacleDetector;
			config.maze1Detector = m_maze1Detector;
			config.maze2Detector = m_maze2Detector;
			config.maze3Detector = m_maze3Detector;
			config.mazeEntranceGuideDetector = m_mazeEntranceGuideDetector;
			config.outerWallDetector = m_outerWallDetector;
			config.dropAreaDetector = m_dropAreaDetector;

			m_robot = new Robot(config, m_gameStage);

			m_robot.setStepMode(true);
			m_robot.setLogger(m_logger, 2);
			m_robot.start(true);
		} catch (Exception ex) {
			Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
			m_logger.log(ex.getMessage());
		}
	}

	@Override
	public void onStop() {
		if (m_robot != null) {
			m_robot.reset();
			m_robot.quit();
		}
		if (m_speaker != null) {
			m_speaker.speak("Shutting down");
			m_speaker.shutDown();
		}
		if (m_mazeCameraView != null) {
			m_mazeCameraView.onDeactivated();
		}
		super.onStop();
	}

	@Override
	public void onResume() {
		try {
			Robot.DETECT_FRONT_WALL_INDEX = SettingsActivity
					.getJunctionIndexDistance(this);
			Robot.LEFT_MOVEBACKWARD_WITHOUT_FRONT_WALL = SettingsActivity
					.getLeftJunctionMovebackDistance(this);
			Robot.RIGHT_MOVEBACKWARD_WITHOUT_FRONT_WALL = SettingsActivity
					.getRightJunctionMovebackDistance(this);
			Robot.UTURN_MOVE_INDEX = SettingsActivity
					.getUTurnMovebackDistance(this);

			if (m_robot != null) {
				m_robot.setStepMode(SettingsActivity.useStepMode(this));
			}

			m_modbusMaster.connect("COM1");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Toast.makeText(this, "Failed to connect to the modbus slave",
					Toast.LENGTH_LONG).show();
		}

		super.onResume();
		m_mazeCameraView.onActivated();
	}

	@Override
	public void onPause() {
		m_modbusMaster.disconnect();
		super.onPause();
		m_mazeCameraView.onDeactivated();
	}

	private void setupStateSpinner() {
		Spinner state = (Spinner)findViewById(R.id.spinner_states);
		
		state.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int pos, long id) {
				switch (pos) {
				/*
		        <item>Find treasure</item>
		        <item>Approach treasure</item>
		        <item>Pick treasure</item>
		        <item>Find maze</item>
		        <item>Approach maze</item>
		        <item>Find maze entrance</item>
		        <item>Find drop area</item>
		        <item>Drop treasure</item>
		        <item>Exit maze</item>
		        */
				case 0:
					m_newState = RobotRunningState.FindingTreasure;
					break;
					
				case 1:
					m_newState = RobotRunningState.ApproachingTreasure;
					break;
					
				case 2:
					m_newState = RobotRunningState.PickingTreasure;
					break;
					
				case 3:
					m_newState = RobotRunningState.FindingMaze;
					break;
					
				case 4:
					m_newState = RobotRunningState.ApproachingMaze;
					break;
					
				case 5:
					m_newState = RobotRunningState.FindingMazeEntrance;
					break;
					
				case 6:
					m_newState = RobotRunningState.FindingDroppingArea;
					break;
					
				case 7:
					m_newState = RobotRunningState.DroppingTreasure;
					break;
					
				case 8:
					m_newState = RobotRunningState.ExitingMaze;
					break;
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				m_newState = null;
			}
			
		});
	}
	
	private void setupSetStateButton() {
		Button set = (Button)findViewById(R.id.button_set_state);
		
		set.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				if (m_robot != null && m_newState != null) {
					
					AlertDialog.Builder builder = new AlertDialog.Builder(RobotActivity.this);
					
			    	builder
			    	.setTitle("Do you want to change the sequence?")
			    	.setMessage("Are you sure?")
			    	.setIcon(android.R.drawable.ic_dialog_alert)
			    	.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			    	    public void onClick(DialogInterface dialog, int which) {			      	
			    	    	//Yes button clicked, do something
					    	m_logger.log("Set new state to " + m_newState);
							m_robot.setNewRunningState(m_newState);
			    	    }
			    	})
			    	.setNegativeButton("No", null)						//Do nothing on no
			    	.show();
				}
			}
			
		});
	}
	
	private void setupRestartButton() {
		Button restart = (Button) findViewById(R.id.button_restart);
		final Button pauseResume = (Button) findViewById(R.id.button_pause_resume);

		restart.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (m_robot != null) {
					m_robot.restart();
					
					pauseResume.setEnabled(true);
					pauseResume.setText("Pause");
				}
			}

		});
	}

	private void setupStopButton() {
		Button stop = (Button) findViewById(R.id.button_stop);
		final Button pauseResume = (Button) findViewById(R.id.button_pause_resume);

		stop.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (m_robot != null) {
					m_robot.stop();
					
					pauseResume.setEnabled(false);
				}
			}

		});
	}
	
	private void setupRobotPauseResumeButton() {
		final Button pauseResume = (Button) findViewById(R.id.button_pause_resume);

		pauseResume.setEnabled(false);

		pauseResume.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (m_robot != null) {
					if (m_robot.isPaused()) {
						m_robot.resume();
						
						pauseResume.setText("Pause");
					}
					else {
						m_robot.pause();
						
						pauseResume.setText("Resume");
					}
				}
			}

		});
	}

	private void setupClearLogButton() {
		final Button clearLog = (Button)findViewById(R.id.button_clear_log);
		
		clearLog.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				TextView logDisplay = (TextView) findViewById(R.id.text_log);
				logDisplay.setText("");
			}
			
		});
	}
	
	private void setupCopyLogButton() {
		final Button copyLog = (Button)findViewById(R.id.button_copy_log);
		final ClipboardManager clipboard = (ClipboardManager)
		        getSystemService(Context.CLIPBOARD_SERVICE);
		
		final TextView logDisplay = (TextView) findViewById(R.id.text_log);
		
		copyLog.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				ClipData clip = ClipData.newPlainText("robot1025", logDisplay.getText().toString());
				clipboard.setPrimaryClip(clip);
			}
		});
	}
	public void playSound(Context context) {
		try {
			Uri soundUri = RingtoneManager
					.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

			MediaPlayer mMediaPlayer = new MediaPlayer();
			mMediaPlayer.setDataSource(context, soundUri);

			final AudioManager audioManager = (AudioManager) context
					.getSystemService(Context.AUDIO_SERVICE);

			if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
				mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
				mMediaPlayer.setLooping(true);
				mMediaPlayer.prepare();
				mMediaPlayer.start();
			}
		} catch (Exception ex) {
			Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
		}
	}
}
